package com.yxh.www.author.conf;

import com.yxh.www.apiscan.entity.ServerApi;
import com.yxh.www.apiscan.entity.ServerApiKey;
import com.yxh.www.author.domain.SmServerApi;
import com.yxh.www.author.service.SmServerApiService;
import com.yxh.www.redis.client.RedisListService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


/**
 * <p>
 *  API 接口信息更新
 * </p>
 *
 * @author yangxiaohui
 * @since 2020/5/11
 */
@Slf4j
@Component
@EnableScheduling
@SuppressWarnings("all")
public class ServerUpdateConfig {
    private final RedisListService redisListService;
    private final RedisTemplate<String,Object> redisTemplate;
    private final SmServerApiService smServerApiService;
    private Set<String> apiHashSet=new HashSet<>();

    public ServerUpdateConfig(List<ServerApi> serverApis, RedisListService redisListService, RedisTemplate<String, Object> redisTemplate, SmServerApiService smServerApiService) {
        this.redisListService = redisListService;
        this.redisTemplate = redisTemplate;
        this.smServerApiService = smServerApiService;
        this.initApiHashSet();
        this.updateServerApis();
        smServerApiService.updateServerApiToRedis(redisTemplate);
    }

    @Scheduled(cron = "0 */1 * * * ?")
    public void updateServerApis(){
        // 是否有待加载的API集合
        long serverApiKeyCount=redisListService.count("ServerApiKeys");
        if (serverApiKeyCount>0){
            log.info("监听到新的Api集合，开始加载...");
            for (long i=0;i<serverApiKeyCount;i++){
                ServerApiKey serverApiKey=redisListService.popListRight("ServerApiKeys");
                log.info("加载服务API:{}",serverApiKey);
                if (!apiHashSet.contains(serverApiKey.getApiHash())){
                    // 持久化接口数据
                    List<ServerApi> serverApiList =redisListService.list(serverApiKey.getApiKey());
                    if (serverApiList.size()>0){
                        // 获取ServerID
                        String serverId=serverApiKey.getApiKey().split("_")[1];
                        smServerApiService.updateSmServerApiByServerId(serverId,this.buildSmServerApi(serverApiList,serverApiKey.getApiHash()));
                        // 更新Redis数据
                        smServerApiService.updateServerApiToRedis(redisTemplate);
                    }
                    this.apiHashSet.add(serverApiKey.getApiHash());
                }else {
                    log.info("服务API无变更：{}",serverApiKey.getApiKey());
                }
            }
            log.info("监听到新的Api集合，加载完毕...");
        }

    }

    /**
     * 初始化 ApiHash集合
     */
    private void initApiHashSet(){
        Set<String> dbApiHashs=smServerApiService.listApiHash();
        if (dbApiHashs!=null && dbApiHashs.size()>0){
            apiHashSet.addAll(dbApiHashs);
        }
    }

    private List<SmServerApi> buildSmServerApi(List<ServerApi> serverApiList,String apiHash){
        LocalDateTime nowTime=LocalDateTime.now();
        return new ArrayList<SmServerApi>(){{
            for (ServerApi serverApi:serverApiList){
                add(new SmServerApi(
                        DigestUtils.md5Hex(serverApi.getApiPath()),
                        serverApi.getApiName(),
                        serverApi.getApiPath(),
                        apiHash,
                        serverApi.getServerId(),
                        serverApi.getServerName(),
                        nowTime,
                        serverApi.getPermissionKeys(),
                        serverApi.getApiType()
                ));
            }
        }};
    }
}
